﻿using Essensoft.Paylink.WeChatPay;
using Essensoft.Paylink.WeChatPay.V3;
using Essensoft.Paylink.WeChatPay.V3.Domain;
using Essensoft.Paylink.WeChatPay.V3.Request;
using Essensoft.Paylink.WeChatPay.V3.Response;
using Microsoft.Extensions.Options;
using Shop.Core.Config;
using Shop.Core.Share;
using Shop.IServices;

namespace Shop.Services
{
    public class WechatAppService : AbstractService, IWechatAppService
    {
        private readonly IWeChatPayClient _client;

        private readonly WeChatPayOptions _weChatPayConfig;

        private readonly CallBackUrlConfig _callBackUrlConfig;

        public WechatAppService(IWeChatPayClient client
            , IOptions<WeChatPayOptions> weChatPayConfig
            , IOptions<CallBackUrlConfig> callBackUrlConfig)
        {
            _client = client;
            _weChatPayConfig = weChatPayConfig.Value;
            _callBackUrlConfig = callBackUrlConfig.Value;
        }

        /// <summary>
        /// 小程序支付
        /// </summary>
        /// <param name="OutTradeNo">外部订单号</param>
        /// <param name="OpenId">用户小程序openId</param>
        /// <param name="amount">金额</param>
        /// <returns></returns>
        public async Task<AppResult<object>> AppletPay(string OutTradeNo, string OpenId , decimal amount)
        {
            var model = new WeChatPayTransactionsJsApiBodyModel
            {
                AppId = _weChatPayConfig.AppId,
                MchId = _weChatPayConfig.MchId,
                Amount = new Amount { Total = Convert.ToInt32(amount * 100), Currency = "CNY" },
                Description = "商品支付",
                NotifyUrl = _callBackUrlConfig.WeChatPay,
                OutTradeNo = OutTradeNo,
                Payer = new PayerInfo { OpenId = OpenId}
            };
            var request = new WeChatPayTransactionsJsApiRequest();
            request.SetBodyModel(model);

            var response = await _client.ExecuteAsync(request, _weChatPayConfig);
            if (!response.IsError)
            {
                var req = new WeChatPayMiniProgramSdkRequest
                {
                    Package = "prepay_id=" + response.PrepayId
                };

                return await _client.ExecuteAsync(req, _weChatPayConfig);
            }
            else
                return Problem("建立微信支付请求失败");
        }

        /// <summary>
        /// 微信转账
        /// </summary>
        /// <param name="outTradeNo">外部单号</param>
        /// <param name="openId">收款用户openId</param>
        /// <param name="name">收款用户姓名</param>
        /// <param name="amount">转账金额</param>
        /// <returns></returns>
        public async Task<WeChatPayTransferBatchesResponse> TransferBatches(string outTradeNo, string openId, string name, decimal amount)
        {
            var model = new WeChatPayTransferBatchesBodyModel
            {
                AppId = _weChatPayConfig.AppId,
                OutBatchNo = outTradeNo,
                TotalAmount = Convert.ToInt32(amount * 100),
                TotalNum = 1,
                TransferDetailList = new List<TransferDetail> {
                    new TransferDetail
                    {
                        OutDetailNo = outTradeNo,
                        TransferAmount = Convert.ToInt32(amount * 100),
                        UserName = name,
                        OpenId = openId,
                        TransferRemark = "迪亚尔提现"
                    }
                }
            };
            var request = new WeChatPayTransferBatchesRequest();
            request.SetBodyModel(model);

            return await _client.ExecuteAsync(request, _weChatPayConfig);
        }
    }
}
